package resfoods.controller;

import com.yc.api.CartApi;
import com.yc.biz.CartInfoBiz;
import com.yc.entity.AddrInfo;
import com.yc.entity.MemberInfo;
import com.yc.utile.DateUtil;
import com.yc.utile.QQ_util;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import resfoods.biz.AddrBiz;
import resfoods.config.JwtTokenUtil;
import resfoods.dao.MemberDao;
import resfoods.service.JwtUserDetailsService;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName JwtAuthenticationController
 * @since: 2023/8/21 10:04
 * @auth: kirito
 * @description:
 *
 **/
@RestController
@Slf4j
@RequestMapping("security/freshgood")
@Api(tags = "用户登录授权管理")
public class JwtAuthenticationController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private JwtUserDetailsService userDetailsService;
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private CartApi cartApi;
    @Autowired
    private AddrBiz addrBiz;



    @GetMapping(value = {"hello"})
    public Claims test(@RequestHeader("Authorization") String bearerToken) {
        System.out.println("接受token为：" + bearerToken);
        String token = bearerToken.substring(7);
        Claims c = jwtTokenUtil.getAllClaimFromToken(token);
        return c;
    }

    /**
     * 登出
     * @param token
     * @param session
     * @return
     */
    @GetMapping({"/loginOut"})
    public Map<String, Object> loginOut(@RequestHeader("Authorization") String token, HttpSession session) {
        Map<String, Object> result = new HashMap<>();
        session.removeAttribute("user");
        session.invalidate();
        result.put("code", 1);
        return result;
    }

    /**
     * 发送QQ验证码
     */
    @RequestMapping(value = "emailCode.action", method = {RequestMethod.POST,RequestMethod.GET})
    public Map<String,Object> emailCode(String QQ) throws Exception {
        String emailCode = QQ_util.achieveCode();
        Map<String, Object> map = new HashMap<>();
        QQ_util.sendCode(QQ,emailCode);
        log.info("随机验证码为：" + emailCode);
        map.put("yzm",emailCode);
        return map;
    }
    /**
     * 注册
     */
    @RequestMapping(value = "register.action", method = {RequestMethod.POST,RequestMethod.GET})
    public Map<String,Object> Register(String username, String pwd,
                          String QQ, String tel) throws Exception {
        BCryptPasswordEncoder be = new BCryptPasswordEncoder();
        Map<String, Object> map = new HashMap<>();
        MemberInfo member = new MemberInfo();
        member.setPwd(be.encode(pwd));
        member.setNickName(username);
        member.setEmail(QQ);
        member.setTel(tel);
        member.setStatus(1);
        member.setRegDate(DateUtil.formatDateTime());
        log.info(member.toString());
        int insert = memberDao.insert(member);
        map.put("code", insert);
        return map;
    }

    @ApiOperation(value = "用户登陆操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true),
            @ApiImplicitParam(name = "pwd", value = "密码", required = true)
    })
    @RequestMapping(value = "resuser.action", method = {RequestMethod.POST,RequestMethod.GET})
    public Map<String, Object> createAuthenticationToken(String username, String pwd, String valcode, HttpSession session) throws Exception {
        Map<String, Object> result = new HashMap<>();
        String code = (String) session.getAttribute("code");
        if (!code.equals(valcode)) {
            result.put("code", 0);
            result.put("msg", "验证码错误");
            return result;
        }
        authenticate(username,pwd);
        final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        final String token = jwtTokenUtil.generateToken(userDetails);

        MemberInfo user = userDetailsService.findByUsername(username);
        if (user.getStatus() != 1) {
            result.put("code", 2);
            return result;
        }
        session.setAttribute("user", user);
        result.put("code", 1);
        result.put("token", token);
        return result;
//        return ResponseEntity.ok(new JwtResponse(token));
    }
    @RequestMapping(value = {"loginCheck"},method = {RequestMethod.GET,RequestMethod.POST})
    public Map<String, Object> loginCheck(@RequestHeader("Authorization") String bearerToken, HttpSession session) {
        Map<String, Object> result = new HashMap<>();
        if (session.getAttribute("user") == null) {
            result.put("code", 0);
            result.put("msg", "用户暂未登录");
            return result;
        }
//        System.out.println("接受到的token为：" + bearerToken);
        String token = bearerToken.substring(7);
        MemberInfo user = (MemberInfo) session.getAttribute("user");
        UserDetails ud = userDetailsService.loadUserByUsername(user.getNickName());
        boolean b = jwtTokenUtil.validateToken(token, ud);

        List<Map<String, Object>> byMno = cartApi.findByMno(user.getMno());
        List<AddrInfo> addr = addrBiz.findBymno(user.getMno());

        if (b) {
            result.put("code", 1);
            result.put("user", user);
            result.put("cartList", byMno);
            result.put("address",addr);
        } else {
            result.put("code", 0);
        }
        return result;
    }

    private void authenticate(String username, String pwd) throws Exception {
        try {
            //调用认证管理器  对输入的用户名和密码进行验证
            //会调数据库查询
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, pwd));
        }catch (DisabledException e) {
            throw new Exception("USER_DISABLED", e);
        }catch (BadCredentialsException e) {
            throw new Exception("INVALID_CREATEDENTITALS", e);
        }
    }
}
